package com.unicom.wostore.dsp.utils;

import net.sf.json.JSONObject;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;


import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 网络请求操作的工具类
 * Created by Huangjie on 2017/2/22.
 */
public class HttpUtil {

    static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);
    public static class UTF8PostMethod extends PostMethod {
        public UTF8PostMethod(String url){
            super(url);
        }
        public String getRequestCharSet() {
            return "UTF-8";
        }
    }


    /*
     *获取外网真实地址
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request){
        String ip = request.getHeader("X-Real-IP");

        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }

        ip = request.getHeader("X-Forwarded-For");
        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
           //多次反向代理后会有多个IP值，第一个为真实IP
            int index = ip.indexOf(",");
            if(index != -1){
                return ip.substring(0,index);
            }else {
                return ip;
            }
        }else {
            return request.getRemoteAddr();
        }
    }





    public static String get(String url,Map<String, String> paramMap){

        HttpClient httpClient = new HttpClient();
        StringBuilder burl = new StringBuilder(url);

        if(paramMap != null && paramMap.size() >0 ){
            int i=1;
            for(String key:paramMap.keySet()){
                if(StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(paramMap.get(key))){
                    try {
                        burl.append(i==1?"?":"&").append(key).append("=").append(URLEncoder.encode(paramMap.get(key),"UTF-8"));
                        i++;
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }


                }
            }
        }

        System.out.print("Request URL="+burl.toString());

        StringBuilder sb = new StringBuilder();
        GetMethod get = new GetMethod(burl.toString());

        get.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
        Reader reader = null;
        int state = 0;

        try {
            state = httpClient.executeMethod(get);
            if (state == 200) {
                reader = new InputStreamReader(get.getResponseBodyAsStream(), "UTF-8");
                int c = 0;
                while ((c = reader.read()) != -1) {
                    sb.append((char) c);
                }
            } else {
                logger.error("GET Request url=" + url + " . Response State is not 200. Is " + state);
            }
        } catch (HttpException e) {
            logger.error("REST Request url=" + url + " . HttpException occured.", e);
            return null;
        } catch (IOException e) {
            logger.error("REST Request url=" + url + " . IOException occured.", e);
            return null;
        }finally {
            get.releaseConnection();
            if (reader != null){
                try{
                    reader.close();
                }catch (IOException e){
                    logger.error("REST Request url=" + url + " . reader.close() IOException occured.", e);
                }
            }
        }
        return sb.toString();

    }





    /**
     * Post URL with JSON data
     * @param url
     * @param jsonObj
     * @return
     */
    public static JSONObject postJson(String url,JSONObject jsonObj,Map<String ,String> headerMap){

        if (jsonObj==null)
            return null;

        Reader reader = null;
        HttpClient client = new HttpClient();
        PostMethod method = new UTF8PostMethod(url);
        //Post Data Type
        method.setRequestHeader("Content-Type", "application/json");


        try {
            String jsonParamStr = jsonObj.toString();


            List<Header> headers = new ArrayList<Header>();
            if(headerMap !=null){
                for(String key : headerMap.keySet()){
                    if(StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(headerMap.get(key))){
                        headers.add(new Header(key,URLEncoder.encode(headerMap.get(key),"UTF-8")));
                    }
                }
            }

            client.getHostConfiguration().getParams().setParameter("http.default-headers", headers);


            if (jsonParamStr!=null && !jsonParamStr.trim().equals("")) {
                RequestEntity requestEntity = new StringRequestEntity(jsonParamStr, "application/json", "UTF-8");
                method.setRequestEntity(requestEntity);
                //method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
                //method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, REQ_TIME_OUT);
            }

            int statusCode = client.executeMethod(method);
            logger.info("Request URL is "+url+",status code="+statusCode);
            if(statusCode != HttpStatus.SC_OK){
                return null;
            }

            StringBuffer sb =new StringBuffer();
            reader = new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8");
            int c = 0;
            while ((c = reader.read()) != -1) {
                sb.append((char) c);
            }
            String response = sb.toString();
            JSONObject responseJson = JSONObject.fromObject(response);
            return responseJson;
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        } catch (HttpException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }finally {
            method.releaseConnection();
            if (reader != null){
                try{
                    reader.close();
                }catch (IOException e){
                    logger.error(e.getMessage());
                }
            }
        }
        return null;
    }


    public static String EncoderByMD5(String str){
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            BASE64Encoder base64Encoder = new BASE64Encoder();

            String newStr = base64Encoder.encode(md5.digest(str.getBytes("utf-8")));
            return newStr;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
}
